Skip to content

spike: transaction fixture network and envelope portability - #83

Merged
knytcomics-ui merged 2 commits into
Gryd-lock:mainfrom
devmasalati:spike/transaction-fixture-portability
Aug 24, 2026
Merged

spike: transaction fixture network and envelope portability#83
knytcomics-ui merged 2 commits into
Gryd-lock:mainfrom
devmasalati:spike/transaction-fixture-portability

Conversation

@devmasalati

@devmasalati devmasalati commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

closes #74

Spike question

Should fixtures remain TESTNET-only, or support multiple passphrases, signed envelopes, fee bumps, and network variants?


Findings summary

The passphrase is invisible in the XDR

TransactionBuilder.fromXDR accepts any passphrase without error. Wrong passphrase → wrong transaction hash, silently. Verified empirically on all three existing fixtures:

payment.xdr decoded under TESTNET: hash = f8310e15760cc1c2...
payment.xdr decoded under PUBLIC:  hash = 80b951bebbf01013...  ← different, no error
Operations: identical in both cases

The XDR encoding does not embed the passphrase. It is purely a caller concern. Any consumer that guesses or defaults to the wrong passphrase will silently compute wrong transaction hashes.

Multi-network support is not warranted (Strategy B rejected)

All fixture addresses are synthetic TESTNET data — they are meaningless on PUBLIC. Adding PUBLIC variants would double fixture count, require consumers to implement passphrase-selection logic, and produce no additional evaluation signal. Strategy A (TESTNET-only with explicit machine-readable metadata) is the correct path.

See §3 of docs/spike-transaction-portability.md for the full strategy comparison table.

Fee-bump is the critical missing envelope type

envelopeTypeTxFeeBump returns a FeeBumpTransaction object — a distinct class from Transaction. A decoder that reads .source on it receives the outer fee-bump source (the account paying the fee), not the inner transaction initiator. It must call .innerTransaction.source and .innerTransaction.operations to reach the data that needs risk-scoring. This decoder path was previously untested — there was no fee-bump fixture.

Signed fixtures are premature

Signing requires a secret key, which cannot be committed (blocked by scripts/check-secrets.mjs). No extension decode path currently requires signature verification. Revisit when the extension gains a verify-before-relay feature.


Deliverables

transactions/index.json (new)

Machine-readable fixture index. For each XDR file:

Field Purpose
network TESTNET — explicit, not implied
passphrase Full passphrase string to pass to fromXDR
envelopeType envelopeTypeTx or envelopeTypeTxFeeBump
signed false — explicit unsigned declaration
stellarHashTestnet Transaction hash computed under TESTNET passphrase
feeBumpSource (fee-bump only) outer fee source account
source Inner tx source / transaction initiator
operations Array of { index, type, destination?, asset?, amount? }
innerTransaction (fee-bump only) inner tx hash + source

Closes the silent-wrong-passphrase risk. Consumers read the passphrase from index.json before calling fromXDR, then verify the resulting hash matches stellarHashTestnet.

transactions/fee_bump_payment.xdr (new)

Prototype envelopeTypeTxFeeBump envelope:

Field Value
Envelope type envelopeTypeTxFeeBump
Fee-bump source (outer) GA4HFFSHZ7PA... (clean_wallet_2)
Inner tx source GCRRYBV5IY7D... (clean_wallet_1)
Inner operation payment to GCRNKXJJLZND... (suspicious_wallet_1)
Outer hash (TESTNET) 7ab7ae0df710a6d3...
Inner hash (TESTNET) f8310e15760cc1c2... (= payment.xdr hash)
Signed No

Verified with the Stellar SDK: FeeBumpTransaction class confirmed, both hashes match, inner ops extracted correctly.

docs/spike-transaction-portability.md (new)

Full spike findings document:

  1. Current state inventory — all assumptions explicitly listed
  2. Six investigation areas (passphrase, PUBLIC/TESTNET, signed/unsigned, fee-bump, hashes, metadata)
  3. Strategy A vs B comparison table (realism, reproducibility, security, consumer complexity, storage, compatibility)
  4. Prototype details with verified hashes
  5. Hash/signature/passphrase implication table — what breaks if each assumption is wrong
  6. Recommendations — ordered by priority
  7. Follow-up issues with priority and owner

transactions/README.md (modified)

Added:

  • Opening note pointing to index.json with passphrase warning
  • fee_bump_payment.xdr fixture section with envelope table, operations table, and a note explaining the inner-vs-outer source decoder requirement

Acceptance criteria

Criterion Met by
Current assumptions inventoried docs/spike-transaction-portability.md §1 — all fixture properties listed
Two portability strategies compared §3 — Strategy A vs B full comparison table
One representative variant prototyped transactions/fee_bump_payment.xdr + index.json
Hash/signature/passphrase implications documented §2 and §5 — empirical proof + implication table

Follow-up issues

Issue Priority Repo
Add fee-bump decode path to grydlock-extension decoder High extension
Add scripts/generate-transactions.mjs for reproducible XDR generation Medium testkit
Investigate muxed account (M...) address handling in decoder Low extension

Cross-repository impact

  • grydlock-extension — decoder must handle FeeBumpTransaction (traverse .innerTransaction). This is the primary actionable follow-up.
  • grydlock-oracle-adapter — no changes needed; fixture shape is unchanged.
  • grydlock-research — should read transactions/index.json for passphrase when decoding fixtures.

Investigates whether fixtures should support multiple passphrases, signed
envelopes, fee bumps, and network variants. Delivers findings document and
the two concrete artifacts the spike recommends.

Key findings:
- TransactionBuilder.fromXDR accepts any passphrase without error. Wrong
  passphrase yields wrong transaction hash silently — verified: same XDR
  decoded under TESTNET (f8310e15...) vs PUBLIC (80b951be...) produces
  identical operations but different hashes.
- Multi-network support (Strategy B) rejected: fixture addresses are
  synthetic TESTNET data, meaningless on PUBLIC. Doubles storage and adds
  consumer disambiguation complexity with no evaluation benefit.
- Fee-bump (envelopeTypeTxFeeBump) is the critical missing envelope type.
  FeeBumpTransaction is a distinct class; .source returns the outer fee
  source, not the inner tx initiator. Decoder must traverse
  .innerTransaction. Previously untested.
- Signed fixtures deferred: no extension decode path requires them;
  secret keys cannot be committed.

Deliverables:
- transactions/index.json: machine-readable index with passphrase,
  envelopeType, signed flag, stellarHashTestnet, and per-operation
  metadata for all four fixtures.
- transactions/fee_bump_payment.xdr: prototype envelopeTypeTxFeeBump
  wrapping payment.xdr. Outer fee source: clean_wallet_2; inner tx
  source: clean_wallet_1. Outer hash: 7ab7ae0d...; inner: f8310e15...
- docs/spike-transaction-portability.md: full findings with inventory,
  strategy comparison, prototype details, and follow-up issues.
- transactions/README.md: index.json reference + fee-bump section.
- CHANGELOG.md: [Unreleased] updated with spike deliverables.

Follow-up issues:
- Add fee-bump decode path to grydlock-extension decoder (High)
- Add scripts/generate-transactions.mjs for reproducible XDR gen (Med)
- Investigate muxed account (M...) address handling in decoder (Low)
@knytcomics-ui
knytcomics-ui merged commit 7064404 into Gryd-lock:main Aug 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Spike] Evaluate network and envelope portability for transaction fixtures

2 participants